<?php

if (!defined('IN_XLP')) {
    exit('Access Denied!');
}

/**
 * Description of noticeAction
 * 社区通知消息
 * @author xlp
 */
class noticeAction extends commonAction {

    function __construct() {
        parent::__construct();
        parent::_checkLogin();
        $this->noticeLevel = array('物业', '社区', '街道');
        $this->newsStatus = array('不被动推', '推送');
        $this->noticeType = array( 2 => '系统广播');
        $this->newsType = array(1 => '单图文', 2 => '多图文');
        $this->res = null; //群发反馈数据
        $this->masssendCount = 1000; //单次群发人数
        $this->serviceCount = 30; //系统广播单次群发人数
    }

    function index() {
        $p = $this->_getid('p');
        $act = $this->_get('act', 'all');
        $type = $this->_getid('type', 0);
        $where = array('aid' => admin::$adminInfo['aid'], 'fid' => 0);
        if ($type) {
            $where['type'] = ($type - 1);
        }
        $rs = M('notice')->where($where)->page($p)->order('nid desc')->findAll();
        $this->assign(array('rs' => $rs, 'p' => $p, 'total' => M('notice')->getTotal(), 'noticeLevel' => $this->noticeLevel, 'newsStatus' => $this->newsStatus, 'noticeType' => $this->noticeType));
        $this->assign(array('type' => $type, 'act' => $act));
        $this->display();
    }

    function tlist() {
        $p = $this->_getid('p', 1);
        $id = $this->_getid('id', 0);
        $isAjax = $this->_getid('isajax', 0);
        if (!$p) {
            showError('参数丢失');
        }
        $where = array('aid' => admin::$adminInfo['aid'], 'nid' => $id);
        $rs = M('notice')->field('nid AS id,source_id,title,description,infotime')->where($where)->find();
        $result = array();
        if ($rs) {
            if ($rs['source_id']) {//图文素材
                $result[0] = $this->getNewsList($rs['source_id']);
            } else {
                $rs['picurl'] = '';
                $rs['url'] = U('notice/detail', array('id' => $rs['id'], 'type' => 'notice'));
                $result[0]['type'] = 'one';
                $result[0]['isOk'] = true;
                $result[0]['header'] = $rs;
                $result[0]['items'] = array();
            }
        }
//        z($result);
        $this->assign(array('rs' => $result));
        if ($isAjax) {
            if ($result) {
                $this->JsonReturn('ok', $this->getFetch(), 1);
            } else {
                $this->JsonReturn('nodata');
            }
        } else {
            $this->display('list');
        }
    }

    function detail() {
        $id = $this->_getid('id');
        $type = $this->_get('type', 'notice');
        if (!$id) {
            showError('参数丢失');
        }
        if ($type == 'news') {
            $rs = M('article')->where(array('id' => $id, 'aid' => admin::$adminInfo['aid']))->find();
        } else {
            $rs = M('notice')->where(array('nid' => $id, 'aid' => admin::$adminInfo['aid']))->find();
        }
        if (!$rs) {
            showError('文章不存在或已删除');
        }
        if ($rs && isHave($rs['url']) && !isHave($rs['content'])) {
            jumpTo($rs['url']);
            exit;
        }
        $rs['content'] = nl2br($rs['content']);
        $this->assign('rs', $rs);
        $this->display();
    }

    function deal() {
        $id = $this->_postid('id');
        $do = $this->_post('do');
        if (!$id) {
            $this->JsonReturn('参数丢失');
        }
        if (!in_array($do, array('up', 'down'))) {
            $this->JsonReturn('参数丢失');
        }
        $status = $do == 'up' ? 1 : 0;
        M('notice')->update(array('status' => $status), 'aid=' . admin::$adminInfo['aid'] . ' AND (nid=' . $id . ' OR fid=' . $id . ')');
        $this->JsonReturn('ok', $id, 1);
    }

    //添加单条图文
    function add() {
        $news = M('article')->field('id,title,type')->where(array('cid' => 20, 'fid' => 0, 'status' => 1))->order('px desc,id desc')->limit(20)->findAll();
        $type = array('year' => '年', 'month' => '月', 'day' => '日');
        $adminCinfig = C('admin', 'counts');
        $noticeLevel = array(
            1 => array(0 => '全部'),
            2 => array(2 => '本街道'),
            3 => array(1 => '本社区'),
            4 => array(0 => '本小区'),
            5 => array(0 => '全部'),
        );
        //检测主动群发和被动群发剩余次数
        $hasPassive = D('adminCount')->checkAdminCounts(admin::$adminInfo['aid'], admin::$adminInfo['groupid'], 'notice_passive');
        $hasActive = D('adminCount')->checkAdminCounts(admin::$adminInfo['aid'], admin::$adminInfo['groupid'], 'notice_active');
        $hasRadio = D('adminCount')->checkAdminCounts(admin::$adminInfo['aid'], admin::$adminInfo['groupid'], 'notice_radio');
        $counts = array(
            'passive' => array(
                'type' => isset($adminCinfig[admin::$adminInfo['groupid']]['notice_passive']['type']) ? $type[$adminCinfig[admin::$adminInfo['groupid']]['notice_passive']['type']] : '',
                'has' => $hasPassive['status'] ? $hasPassive['count'] : 0,
                'unit' => '条'
            ),
            'active' => array(
                'type' => isset($adminCinfig[admin::$adminInfo['groupid']]['notice_active']['type']) ? $type[$adminCinfig[admin::$adminInfo['groupid']]['notice_active']['type']] : '',
                'has' => $hasActive['status'] ? $hasActive['count'] : 0,
                'unit' => '条'
            ),
            'radio' => array(
                'type' => isset($adminCinfig[admin::$adminInfo['groupid']]['notice_radio']['type']) ? $type[$adminCinfig[admin::$adminInfo['groupid']]['notice_radio']['type']] : '',
                'has' => $hasRadio['status'] ? $hasRadio['count'] : 0,
                'unit' => '条'
            ),
        );
        foreach (array('passive', 'active', 'radio') as $val) {
            if ($counts[$val]['has'] == -1) {
                $counts[$val]['has'] = '不限';
                $counts[$val]['unit'] = '';
            }
        }
//        z($counts);
        $this->assign(array('newsStatus' => $this->newsStatus, 'news' => $news, 'newsType' => $this->newsType, 'counts' => $counts, 'noticeLevel' => $noticeLevel[admin::$adminInfo['groupid']], 'noticeType' => $this->noticeType));
        $this->display('add');
    }

    //保存通知信息
    function post() {
//        z($_POST);
        $objData = array();
        //获取字段内容
        $fieldList = M('notice')->getTableFields();
        foreach ($fieldList['fields'] as $key => $val) {
            $objData[$key] = $val['value'];
        }
        $objData['source_id'] = $this->_postid('source_id', 0);
        $objData['type'] = $this->_postid('type', 0); //通知类型 0:被动 1：主动 2:广播
        $objData['title'] = $this->_post('title');
        $objData['content'] = $this->_post('content');
        $objData['description'] = $objData['content'] ? cnsubStr($objData['content'], 120) : '';
        $objData['stime'] = $this->_post('stime');
        $objData['etime'] = $this->_post('etime');
        $objData['aid'] = admin::$adminInfo['aid'];
        $objData['village_id'] = admin::$adminInfo['village_id'];
        $objData['infotime'] = TIME;
        $objData['status'] = $this->_postid('status', 0); //被动通知推送类型 0：不推送，1：推送
        //检查当前帐号是否超出发布的次数
        switch ($objData['type']) {
            case 0:
                $type = 'notice_passive';
                break;
            case 1:
                $type = 'notice_active';
                break;
            case 2:
                $type = 'notice_radio';
                break;
            default :
                $type = 'notice_passive';
        }
        $has = D('adminCount')->checkAdminCounts(admin::$adminInfo['aid'], admin::$adminInfo['groupid'], $type);
        if (!$has['status']) {
            $this->JsonReturn($has['msg']);
        }
        if (!$objData['title']) {
            $this->JsonReturn('标题不能为空');
        }
        $objData['stime'] = inTime($objData['stime']);
        $objData['etime'] = inTime($objData['etime']);

        $noticeWay = $this->_postid('notice_way', 0); //消息类型 0:文本 1:图文
        //处理通知数据
        //1、当前用户身份级别，如果是街道或者社区，需要取出他所辖的所有的小区然后依次写入通知
        //TODO:2014-07-23 xia 暂时不支持街道或者社区发送通知
        //2、根据通知类型分别处理不同的数据
        if ($objData['type'] == 0 || $objData['type'] == 2) {//被动通知或者广播
            if (!$objData['stime'] || !$objData['etime']) {
                $this->JsonReturn('请输入通知有效时间');
            }
            if ($noticeWay == 0) {//普通文本消息
                $objData['source_id'] = 0;
                if (getStrLen($objData['content']) > 600) {
                    $this->JsonReturn('通知长度不能超过600个字');
                }
            } else {//图文消息
                if (!$objData['source_id']) {
                    $this->JsonReturn('请选择图文消息');
                }
                $objData['content'] = '';
                $objData['description'] = '';
            }
        } else {
            if ($noticeWay == 0) {//普通文本消息
                if (getStrLen($objData['content']) > 1000) {
                    $this->JsonReturn('通知长度不能超过600个字');
                }
            } else {//图文消息
                $this->JsonReturn('抱歉，暂不支持群发图文消息');
            }
        }
//        print_r($_POST);
//    z($objData);
        $ids = array();
        switch (admin::$adminInfo['groupid']) {
            case 1://系统管理员
                $objData['notice_level'] = 0;
//                $this->JsonReturn('抱歉，你所在的组别无此权限');
                break;
            case 2://街道管理员
                $ids = D('area')->getVillageIdByAid(admin::$adminInfo['aid']);
                $objData['notice_level'] = 2;
                break;
            case 3://社区管理员
                $ids = D('area')->getVillageIdByAid(admin::$adminInfo['aid']);
                $objData['notice_level'] = 1;
                break;
            case 4://小区管理员
                $objData['notice_level'] = 0;
        }
//        z($ids);
        $objDataList = array();
        $id = M('notice')->insert($objData);
        if (!$id) {
            $this->JsonReturn('发布失败，请检查');
        }

        //根据用户组将消息下发到所属的所有小区
        // if ($ids) {
        //     $objData['fid'] = $id;
        //     foreach ($ids as $val) {
        //         $objData['village_id'] = $val;
        //         $objDataList[] = $objData;
        //     }
        //     M('notice')->insertAll($objDataList);
        // }
        // D('adminCount')->addAdminCount(admin::$adminInfo['aid'], admin::$adminInfo['groupid'], $type);
        //3、群发消息需要立即发送提交
        //TODO:2014-07-23 xia 暂时不支持群发图文，待后期完善解决
        $objData['nid'] = $id;
        $masssend = 0;
        if ($objData['type'] == 1 && $noticeWay == 0) {//主动群发
            if (admin::$adminInfo['village_id']) {
                $ids[] = admin::$adminInfo['village_id'];
            }
            if (!$ids) {
                $this->JsonReturn('没有所属小区，请检查');
            }
            $masssend = $this->getSendMasssendUserList($objData, $ids);
        }
        if ($objData['type'] == 2) {//广播
            // if (admin::$adminInfo['village_id']) {
            //     $ids[] = admin::$adminInfo['village_id'];
            // }
            // if (!admin::$adminInfo['isAdmin'] && !admin::$adminInfo['isEditor'] && !$ids) {
            //     $this->JsonReturn('没有所属小区，请检查');
            // }
            $masssend = $this->getSendServiceUserList($objData, $ids);
        }
        $this->JsonReturn('ok', array('id' => $id, 'masssend' => $masssend), 1);
    }

    function delete() {
        $id = $this->_postid('id');
        if (!$id) {
            showError('参数丢失');
        }
        M('notice')->delete("nid IN (" . $id . ") AND aid=" . admin::$adminInfo['aid']);
        M('notice')->delete("fid IN (" . $id . ") AND aid=" . admin::$adminInfo['aid']);
        $this->JsonReturn('ok', null, 1);
    }

    function send() {
        $p = $this->_getid('p', 1); //分页
        $total = $this->_getid('total', 0); //总页数
        $jId = $this->_getid('j', 0); //当前条目
        $isAjax = $this->_getid('is_ajax', 0); //当前条目
        if ($total && $p > $total) {
            F('weixin/masssend_aid_' . admin::$adminInfo['aid'], null);
            mySession('sendOk', null);
            $this->JsonReturn('操作完成', null, -1);
        }
        $objData = F('weixin/masssend_aid_' . admin::$adminInfo['aid']);
        if (isset($objData['key']) && $objData['key']) {
            $p = $objData['key'];
            unset($objData['key']);
        }
        if (!$objData) {
            $this->returnJson = false;
            mySession('sendOk', null);
            $this->JsonReturn('队列文件不存在');
        }
        if (!isset($objData['total']) || !isHave($objData['type']) || !isHave($objData['nid']) || !isHave($objData['user']) || !isset($objData['user'][($p - 1)])) {
            mySession('sendOk', null);
            $this->JsonReturn('缓存错误', null, -2);
        }
        if (!$total) {
            $total = count($objData['user']);
        }
        $rs = M('notice')->where(array('nid' => $objData['nid']))->find();
        if (!$rs) {
            mySession('sendOk', null);
            $this->JsonReturn('通知信息不存在');
        }
        if ($objData['type'] == 'masssend') {//主动推送
            $this->masssend($rs, $objData['user'][($p - 1)]);
        } elseif ($objData['type'] == 'radio') {//系统广播
            $this->serviceMsg($rs, $objData['user'][($p - 1)]);
        }
        $pushCount = count($objData['user'][($p - 1)]);
        //剔除已发用户
        unset($objData['user'][($p - 1)]);
        //保存当前游标位置
        $objData['key'] = $p + 1;
        F('weixin/masssend_aid_' . admin::$adminInfo['aid'], $objData);
        $sendOk = mySession('sendOk');
        $this->log = '发送情况:第' . $p . '组，共：' . $total . '组，共' . $objData['total'] . '人，已推送' . $sendOk . '人，本次推送：' . $pushCount . '人';
        $this->printMsg = var_export($this->res, true);
        $this->showProgress($p, $total, $jId, $isAjax, $objData['total'], $sendOk);
    }

    /*
     * 群发用户列表
     */

    private function getSendMasssendUserList($rs, $ids) {
        $objData = array();
        $userList = D('member')->query('SELECT b.keyid FROM __TABLE__  AS a LEFT JOIN __PRE__user_bind AS b ON a.uid=b.uid WHERE a.village_id IN (' . implode(',', $ids) . ') AND a.status=1 AND b.type=\'wx\'');
        $userCount = D('member')->where('village_id IN (' . implode(',', $ids) . ') AND status=1')->count();
        if ($userCount) {
            $users = array();
            if ($userCount > $this->masssendCount) {//1000以上的需要队列处理
//                foreach ($userList as $val) {
//                    $users[] = $val['keyid'];
//                }
                $users = array_map('array_shift', $userList);
                $objData = array_chunk($users, $this->masssendCount, false); //切割数组  
                F('weixin/masssend_aid_' . admin::$adminInfo['aid'], array('type' => 'masssend', 'nid' => $rs['nid'], 'user' => $objData, 'total' => $userCount));
                return 2;
            } else {
//                foreach ($userList as $val) {
//                    $users[] = $val['keyid'];
//                }
                $users = array_map('array_shift', $userList);
                $this->masssend($rs, $users);
                return 1;
            }
        } else {
            $this->JsonReturn('本区域下暂时没有用户入住');
        }
        return 1;
    }

    /*
     * 广播用户列表
     */

    private function getSendServiceUserList($rs, $ids) {
        $where = '1=1';
        $uids = array();
        if ($ids) {
            $where = ' AND a.village_id IN (' . implode(',', $ids) . ')';
        }
        $stime = TIME - (60 * 60 * 48);
        $userUidList = M('user')->query('SELECT a.uid FROM __TABLE__ AS a LEFT JOIN __PRE__access_log AS b ON a.uid=b.uid'
                . ' WHERE b.create_time>=' . $stime . ' GROUP BY b.uid');
        //z($userUidList);
        if ($userUidList) {
//            foreach($rs as $val){
//                $uids[]=$val['uid'];
//            }
            $uids = array_map('array_shift', $userUidList);
        }
        if (!$uids) {
            $this->JsonReturn('没有符合推送条件的用户(0)');
        }
        $objData = array();
        $userList = M('user')->field('openid')->where('uid IN (' . implode(',', $uids) . ')')->findAll();
        $userCount = M('user')->getTotal();
//        print_r($userList);
//        z(D('member')->getAllSql());
        if ($userCount) {
            $users = array();
            if ($userCount > $this->serviceCount) {//需要队列处理
//                foreach ($userList as $val) {
//                    $users[] = $val['keyid'];
//                }
                $users = array_map('array_shift', $userList);
                $objData = array_chunk($users, $this->serviceCount, false); //切割数组 
                F('weixin/masssend_aid_' . admin::$adminInfo['aid'], array('type' => 'radio', 'nid' => $rs['nid'], 'user' => $objData, 'total' => $userCount));
                return 2;
            } else {
               foreach ($userList as $val) {
                   $users[] = $val['openid'];
               }
                $users = array_map('array_shift', $userList);
                $this->serviceMsg($rs, $users);
                return 1;
            }
        } else {
            $this->JsonReturn('没有符合推送条件的用户(1)');
        }
        return 1;
    }

    /*
     * 主动群发文本消息
     */

    private function masssend($rs, $users) {
        T('weixin/weixin.api');
        $this->weixinApi = new weixinMsgApi();
        $this->res = $this->weixinApi->sendMassMessage(
                array(
                    'touser' => $users,
                    'msgtype' => 'text',
                    'text' => array(
                        'content' => $rs['content']
                    )
                )
        );
        if ($this->res) {
            saveLog('notice/masssend', $this->res);
            return true;
        } else {
            $err = array('code' => $this->weixinApi->errCode, 'msg' => $this->weixinApi->errMsg, 'users' => $users);
            saveLog('notice/masssend', $err);
            $this->JsonReturn('发送失败，请通知管理员', $err, 0);
        }
        $total = mySession('sendOk');
        $total = $total ? $total + count($users) : count($users);
        mySession('sendOk', $total);
        $this->updateSendUsers($rs['nid'], count($users));
        return false;
    }

    //发送客服消息
    private function serviceMsg($rs, $users) {
        //发送通知
        T('weixin/weixin.api');
        $weixinMsgApi = new weixinMsgApi();
        //检查消息类型
        if ($rs['source_id']) {
            $news = $this->replyNews($rs['source_id']);
            //判断新闻素材是否被删除
            if (!$news) {
                $this->JsonReturn('发送失败，新闻素材被删除', null, 0);
            }
            $sendInfo = array(
                'touser' => '',
                'msgtype' => 'news',
                'news' => array(
                    'articles' => $news
                )
            );
        } else {
            $sendInfo = array(
                'touser' => '',
                'msgtype' => 'text',
                'text' => array(
                    'content' => $rs['title'] . "\n" . $rs['content']
                )
            );
        }
        $res = array('ok' => 0, 'err' => 0, 'msg' => array());
        foreach ($users as $val) {
//====================
            $sendInfo['touser'] = $val;
            if ($weixinMsgApi->sendCustomMessage($sendInfo)) {
                $res['ok']+=1;
            } else {
                $res['err']+=1;
                $res['msg'][] = array('openid' => $val, 'code' => $weixinMsgApi->errCode, 'info' => $weixinMsgApi->errMsg);
            }
//====================
        }
        $this->res = array('成功' => $res['ok'], '失败' => $res['err']);
        //将发送失败的保存下来
        if ($res['err']) {
            saveLog('notice/service', $res);
        }
        $total = mySession('sendOk');
        $total = $total ? $total + $res['ok'] : $res['ok'];
        mySession('sendOk', $total);
        $this->updateSendUsers($rs['nid'], $res['ok']);
        return true;
    }

    //回复图文
    private function getNewsList($id) {
        $rs = M('article')->field('id,type,title,description,picurl,infotime')->where(array('id' => $id))->order('id desc')->find();
        $items = array('type' => 'one', 'header' => array(), 'items' => array(), 'isOk' => true);
        if ($rs) {
            $rs['url'] = U('notice/detail', array('id' => $rs['id'], 'type' => 'news'));
            $items['header'] = $rs;
            if ($rs['type'] == 2) {//多条图文时
                $rsItem = M('article')->field('id,title,description,picurl,infotime')->where(array('fid' => $rs['id']))->order('id asc')->limit(0, 8)->findAll();
                if ($rsItem) {
                    $items['type'] = 'more';
                    foreach ($rsItem as $key => $val) {
                        $rsItem[$key]['url'] = U('notice/detail', array('id' => $val['id'], 'type' => 'news'));
                    }
                    $items['items'] = $rsItem;
                }
            }
        } else {
            $items['isOk'] = false;
        }
        return $items;
    }

    //回复图文,供群发使用
    private function replyNews($id) {
        $rs = M('article')->field('id,type,title,content,description,picurl,url,infotime')->where(array('fid' => 0, 'id' => $id))->order('id desc')->find();
        $items = array();
        $result = array();
        if ($rs) {
            $result[] = $rs;
            if ($rs['type'] == 2) {//多条图文时
                $rsItem = M('article')->field('id,title,content,description,picurl,url,infotime')->where(array('fid' => $rs['id']))->order('id asc')->limit(0, 8)->findAll();
                if ($rsItem) {
                    $result = array_merge_recursive($result, $rsItem);
                }
            }
        }
        if ($result) {
            foreach ($result as $val) {
                $url = U('weixin/news/detail', array('id' => $val['id']));
                $url = str_replace('www.', '', $url);
                $items[] = array(
                    'title' => $val['title'],
                    'createTime' => $val['infotime'],
                    'description' => $val['description'],
                    'picurl' => getImgUrl($val['picurl']),
                    'url' => !$val['content'] && $val['url'] ? $val['url'] : $url
                );
            }
        }
        return $items;
    }

    /*
     * 进度条页面
     */

    private function showProgress($p, $total, $j, $isAjax, $users, $send) {
        $config = array(
            'title' => '群发中...请勿关闭页面',
            'pagename' => U('notice/send'),
            'total' => $total,
            'now' => $p,
            'reload' => 0,
            'autoChange' => true,
            'doing' => $this->log,
            'msg' => $this->printMsg,
            'sleepTime' => 1000,
            'j' => $j,
            'users' => $users,
            'send' => $send
        );
        if ($isAjax) {
            $config['isAjax'] = 1;
            $this->assign($config);
            $this->JsonReturn('ok', array(
                'p' => $p,
                'total' => $total,
                'j' => $j,
                'item' => $this->getFetch('show', 'public'),
                'users' => $users,
                'send' => $send
                    ), 1);
        } else {
            $config['isAjax'] = 0;
            $this->assign($config);
            $this->display('show', 'public');
        }
    }

    /*
     * 更新已推送的人数
     */

    private function updateSendUsers($nid, $totals) {
        return $totals ? M('notice')->where(array('nid' => $nid))->setInc('counts', $totals) : 0;
    }

}
